package at.bakery.kippen.test.movebyinertiatest;
import java.util.Arrays;
import java.util.Vector;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.opengl.Matrix;
import android.os.Bundle;
import android.view.Menu;
public class MoveActivity extends Activity {
private SensorManager sensorMan;
private Sensor accSense;
private SensorEventListener accSensorListener;
private Sensor magSense;
private SensorEventListener magSensorListener;
private Sensor gravSense;
private SensorEventListener gravSensorListener;
private float[] accVector = new float[4];
private float[] magVector = new float[4];
private float[] gravVector = new float[4];
// velocity and position
private float[] velocity = new float[4];
private float[] position = new float[2];
private long lastTime = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_move);
Object tmpMan = getSystemService(Context.SENSOR_SERVICE);
if(tmpMan == null) {
System.err.println("No sensor services detected on device. It does not make sense to start, I rather quit myself.");
this.finish();
}
sensorMan = (SensorManager)tmpMan;
// fetch initial time
lastTime = System.nanoTime();
accSense = sensorMan.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
accSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent se) {
accVector = Arrays.copyOf(se.values, 4);
if(gravVector == null || magVector == null) {
return;
}
float[] rotMat = new float[16];
float[] incMat = new float[16];
SensorManager.getRotationMatrix(rotMat, incMat, gravVector, magVector);
float[] invRotMat = new float[16];
Matrix.invertM(invRotMat, 0, rotMat, 0);
float[] accWorld = new float[4];
Matrix.multiplyMV(accWorld, 0, invRotMat, 0, accVector, 0);
// rounded for nicer output
float[] tmpAcc = new float[accWorld.length];
for(int i = 0; i < accWorld.length; i++) {
tmpAcc[i] = (int)accWorld[i];
}
System.out.println("ACC: " + Arrays.toString(tmpAcc));
// computeAndPrintPosition(accWorld);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {}
};
magSense = sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
magSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent se) {
magVector = Arrays.copyOf(se.values, 4);
// System.out.println("MAG: " + Arrays.toString(se.values));
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {}
};
gravSense = sensorMan.getDefaultSensor(Sensor.TYPE_GRAVITY);
gravSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent se) {
gravVector = Arrays.copyOf(se.values, 4);
// System.out.println("GRAV: " + Arrays.toString(se.values));
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {}
};
}
public void computeAndPrintPosition(float[] accWorld) {
// only if acceleration then adjust position
if(accWorld[0]*accWorld[0] + accWorld[1]*accWorld[1] + accWorld[2]*accWorld[2] < 1) {
System.out.println("OLD: " + Arrays.toString(position));
return;
}
// fetch delta time
double timeDelta = (System.nanoTime() - lastTime) * 10E-9 * 10E-5;
for(int i = 0; i < velocity.length; i++) {
velocity[i] += timeDelta * (int)accWorld[i];
}
for(int i = 0; i < position.length; i++) {
position[i] += timeDelta * velocity[i];
}
// tmp pos rounded
float[] roundedPos = new float[position.length];
for(int i = 0; i < position.length; i++) {
roundedPos[i] = (int)position[i];
}
System.out.println("POS: " + Arrays.toString(roundedPos));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.move, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
sensorMan.registerListener(accSensorListener, accSense, Sensor.TYPE_LINEAR_ACCELERATION);
sensorMan.registerListener(magSensorListener, magSense, Sensor.TYPE_MAGNETIC_FIELD);
sensorMan.registerListener(gravSensorListener, gravSense, Sensor.TYPE_GRAVITY);
}
}